package jmine.tec.script.impl;

import jmine.tec.script.ScriptDispatcher;
import jmine.tec.script.ScriptExecutionContext;
import jmine.tec.script.ScriptExecutor;
import jmine.tec.script.ScriptExecutorException;

/**
 * Implementação que apenas delega para um ScriptExecutor com syncronized. NÃO deve ser usado em produção. Claramente gera um gargalo e só
 * deve ser usado para testes.
 * 
 * @author jrenaut
 */
public class SimpleScriptDispatcher implements ScriptDispatcher {

    private ScriptExecutor executor;

    /**
     * Executa o contexto dado.
     * 
     * @param <R> O tipo do resultado
     * @param context o contexto de execução
     * @return R
     * @throws ScriptExecutorException Se um erro ocorrer no dispatch
     */
    public synchronized <R> R dispatchExecution(final ScriptExecutionContext<R> context) throws ScriptExecutorException {
        return this.executor.execute(context);
    }

    /**
     * Devolve as dependêcias do contexto dado.
     * 
     * @param <R> O tipo do resultado
     * @param context o contexto de execução
     * @return R
     * @throws ScriptExecutorException Se um erro ocorrer no dispatch
     */
    public synchronized <R> R dispatchGetDependencies(final ScriptExecutionContext<R> context) throws ScriptExecutorException {
        return this.executor.getDependencies(context);
    }

    /**
     * Devovle os erros de validação para o contexto dado.
     * 
     * @param <R> O tipo do resultado
     * @param context o contexto de execução
     * @return R
     * @throws ScriptExecutorException Se um erro ocorrer no dispatch
     */
    public synchronized <R> R dispatchGetValidations(ScriptExecutionContext<R> context) throws ScriptExecutorException {
        return this.executor.getValidations(context);
    }

    /**
     * Registra este Executor.
     * 
     * @param exec O executor que deve ser usado neste dispatcher
     */
    public synchronized void setScriptExecutors(final ScriptExecutor... exec) {
        this.executor = exec[0];
    }

}
